package com.molichuxing.services.business.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.utils.DateUtil;
import com.molichuxing.services.business.convertor.Convert;
import com.molichuxing.services.business.dto.request.modify.OrderScheduleAuditModifyDto;
import com.molichuxing.services.business.dto.request.modify.OrderScheduleOfflineModifyDto;
import com.molichuxing.services.business.dto.response.*;
import com.molichuxing.services.business.service.OrderScheduleBizService;
import com.molichuxing.services.contants.OrderConst;
import com.molichuxing.services.exception.OrderExceptionCodeEnum;
import com.molichuxing.services.infrastructure.dto.request.create.OrderStatusFlowCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.OrderScheduleRepaymentModifyDto;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @Author: renzhengyu
 * @Description:
 * @Date: Created in 10:49 2019/8/19
 * @Modified By:
 **/
@Service("orderScheduleBizService")
public class OrderScheduleBizServiceImpl implements OrderScheduleBizService {
    private static final Logger logger = LoggerFactory.getLogger(OrderScheduleBizServiceImpl.class);

    @Resource
    private OrderScheduleService orderScheduleService;

    @Resource
    private OrderExclusivelService orderExclusivelService;

    @Resource
    private OrderDealerService orderDealerService;

    @Resource
    private OrderDealerDeliveryService orderDealerDeliveryService;

    @Resource
    private OrderStatusFlowService orderStatusFlowService;

    @Override
    public List<OrderScheduleRelationBizDto> getOrderScheduleRelationBizDto(Long orderCode)
            throws Exception {
        if (orderCode == null) {
            throw new Exception("参数不完整");
        }
        List<OrderScheduleRelationBizDto> bizList = new ArrayList<>();
        // 查询同时还款的订单信息
        List<OrderScheduleRelationDto> relationList = orderScheduleService.getOrderScheduleRelationDto(orderCode);
        if (relationList == null || relationList.size() == 0) {
            throw new Exception("非法入参");
        }
        // 查询车辆数
        Integer carCount = orderDealerService.getCarCount(orderCode);
        if (carCount == null || carCount == 0) {
            throw new Exception("非法入参");
        }

        OrderScheduleRelationBizDto biz = null;
        for (OrderScheduleRelationDto bean : relationList) {
            biz = new OrderScheduleRelationBizDto();
            BeanUtils.copyProperties(bean, biz);
            biz.setCarCount(carCount);
            bizList.add(biz);
        }

        return bizList;
    }

    @Override
    public Paged<OrderScheduleCurrentPeriodBizDto> getOrderScheduleCurrentPeriodList(Map<String, Object> params,
                                                                                     Integer pageNum, Integer pageSize) throws Exception {

        // 还款基础信息
        Paged<OrderScheduleCurrentPeriodDto> currentPeriodPaged = orderScheduleService
                .getDealerOrderCurrentPeriod(params, pageNum, pageSize);
        Paged<OrderScheduleCurrentPeriodBizDto> bizPaged = null;

        if (currentPeriodPaged != null && currentPeriodPaged.getList() != null) {
            bizPaged = new Paged<>();
            List<OrderScheduleCurrentPeriodDto> currentPeriodList = currentPeriodPaged.getList();
            List<OrderScheduleCurrentPeriodBizDto> currentPeriodBizList = new ArrayList<>();
            OrderScheduleCurrentPeriodBizDto currentPeriodBiz = null;

            for (OrderScheduleCurrentPeriodDto bean : currentPeriodList) {
                currentPeriodBiz = new OrderScheduleCurrentPeriodBizDto();
                BeanUtils.copyProperties(bean, currentPeriodBiz);
                // 获取车辆数
                Integer carCount = orderDealerService.getCarCount(bean.getOrderCode());
                if (carCount == null || carCount == 0) {
                    throw new Exception("非法入参");
                }
                currentPeriodBiz.setCarCount(carCount);

                // 获取订单下的车辆id集合
                List<Integer> carIdList = orderDealerDeliveryService.getCarIdListByOrderCode(bean.getOrderCode());
                if (carIdList == null || carIdList.size() == 0) {
                    throw new Exception("非法入参");
                }
                currentPeriodBiz.setCarIdList(carIdList);
                currentPeriodBiz.setPayable(bean.getPayable().add(bean.getDeposit()));
                currentPeriodBizList.add(currentPeriodBiz);

            }
            bizPaged.setList(currentPeriodBizList);
            bizPaged.setPageNum(currentPeriodPaged.getPageNum());
            bizPaged.setPageSize(currentPeriodPaged.getPageSize());
            bizPaged.setPages(currentPeriodPaged.getPages());
            bizPaged.setTotal(currentPeriodPaged.getTotal());

        }

        return bizPaged;
    }

    @Override
    public Paged<OrderScheduleOverdueBizDto> getOrderScheduleOverdueList(Map<String, Object> params, Integer pageNum,
                                                                         Integer pageSize) throws Exception {
        // 还款基础信息
        Paged<OrderScheduleOverdueDto> overduePaged = orderScheduleService.getDealerOrderOverdue(params, pageNum,
                pageSize);
        Paged<OrderScheduleOverdueBizDto> bizPaged = null;

        if (overduePaged != null && overduePaged.getList() != null) {
            bizPaged = new Paged<>();
            List<OrderScheduleOverdueDto> overdueList = overduePaged.getList();
            List<OrderScheduleOverdueBizDto> overdueBizList = new ArrayList<>();
            OrderScheduleOverdueBizDto overdueBiz = null;

            for (OrderScheduleOverdueDto bean : overdueList) {
                overdueBiz = new OrderScheduleOverdueBizDto();
                BeanUtils.copyProperties(bean, overdueBiz);
                // 获取车辆数
                Integer carCount = orderDealerService.getCarCount(bean.getOrderCode());
                if (carCount == null || carCount == 0) {
                    throw new Exception("非法入参");
                }
                overdueBiz.setCarCount(carCount);

                // 获取订单下的车辆id集合
                List<Integer> carIdList = orderDealerDeliveryService.getCarIdListByOrderCode(bean.getOrderCode());
                if (carIdList == null || carIdList.size() == 0) {
                    throw new Exception("非法入参");
                }
                overdueBiz.setCarIdList(carIdList);
                overdueBiz.setPayable(bean.getPayable().add(bean.getDeposit()));
                overdueBizList.add(overdueBiz);

            }
            bizPaged.setList(overdueBizList);
            bizPaged.setPageNum(overduePaged.getPageNum());
            bizPaged.setPageSize(overduePaged.getPageSize());
            bizPaged.setPages(overduePaged.getPages());
            bizPaged.setTotal(overduePaged.getTotal());

        }

        return bizPaged;
    }

    @Override
    public List<OrderScheduleDetailBizDto> getOrderScheduleDetailBizDtoById(List<Integer> ids) throws Exception {
        if (ids == null || ids.size() == 0) {
            throw new Exception("还款计划id不能为空");
        }

        List<OrderScheduleDetailBizDto> orderScheduleDetailList = new ArrayList<>();
        OrderScheduleDetailBizDto orderScheduleDetail = null;
        List<OrderScheduleDto> orderScheduleDtoList = orderScheduleService.getOrderDealerListByIds(ids);
        if (orderScheduleDtoList == null || orderScheduleDtoList.size() == 0) {
            throw new Exception("无还款计划信息");
        }
        for (OrderScheduleDto bean : orderScheduleDtoList) {
            orderScheduleDetail = new OrderScheduleDetailBizDto();
            BeanUtils.copyProperties(bean, orderScheduleDetail);
            if (null != bean.getDeposit()) {
                orderScheduleDetail.setPayable(bean.getPayable().add(bean.getDeposit()));
            }
            // 获取车辆数
            Integer carCount = orderDealerService.getCarCount(bean.getOrderCode());
            if (carCount == null || carCount == 0) {
                throw new Exception("非法入参");
            }
            orderScheduleDetail.setCarCount(carCount);
            orderScheduleDetailList.add(orderScheduleDetail);
        }

        return orderScheduleDetailList;
    }

    /**
     * 根据排期ids查询还款订单信息
     *
     * @param ids 排期ids
     * @return
     */
    @Override
    public List<OrderScheduleOfflineBizDto> getOrderScheduleOffline(List<Integer> ids) {
        List<OrderScheduleOfflineBizDto> result = null;
        List<OrderScheduleDto> orderScheduleDtoList = orderScheduleService.getOrderScheduleDtoListById(ids);
        if (orderScheduleDtoList == null || orderScheduleDtoList.isEmpty()) {
            return result;
        }

        result = new ArrayList<>(ids.size());
        for (OrderScheduleDto orderScheduleDto : orderScheduleDtoList) {
            OrderScheduleOfflineBizDto orderScheduleOfflineBizDto = Convert
                    .toOrderScheduleOfflineBizDto(orderScheduleDto);
            // 查询订单信息
            if (orderScheduleDto.getUserId() != null) {
                // 用户订单
                OrderExclusivelDto orderExclusivelDto = orderExclusivelService
                        .getOrderExclusivel(orderScheduleDto.getOrderCode());
                if (orderExclusivelDto == null) {
                    // 订单不存在
                    logger.error("[getOrderScheduleOffline]订单号：" + orderScheduleDto.getOrderCode() + "对应订单不存在");
                    throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(), "订单信息不存在");
                }
                orderScheduleOfflineBizDto.setCarId(orderExclusivelDto.getCarId());

                result.add(orderScheduleOfflineBizDto);
            } else if (orderScheduleDto.getDealerId() != null) {
                // 经销商订单
            }
        }

        return result;
    }

    /**
     * 线下还款修改排期状态
     *
     * @param modifyDto
     * @return
     * @throws BizException
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Map<Integer, OrderScheduleOfflineBizDto> modifyOrderScheduleByOffline(
            OrderScheduleOfflineModifyDto modifyDto) throws BizException {
        Map<Integer, OrderScheduleOfflineBizDto> result = new HashMap<>(modifyDto.getIds().size());
        // id正序排序
        Collections.sort(modifyDto.getIds());
        // 循环查询排期信息
        for (Integer id : modifyDto.getIds()) {
            OrderScheduleDto orderScheduleDto = orderScheduleService.getOrderSchedule(id);
            if (orderScheduleDto == null) {
                logger.error("[modifyOrderScheduleByOffline]排期id：" + id + "对应排期信息不存在");
                throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(), "排期信息不存在");
            } else if (OrderScheduleStatusEnum.ALREADY.equals(orderScheduleDto.getStatus())) {
                logger.error("[modifyOrderScheduleByOffline]排期id：" + id + "对应排期信息已还款");
                throw new BizException(OrderExceptionCodeEnum.ALREADY.getCode(), "排期信息已还款");
            }
            // 判断排期订单是否为经销商订单且为第一期
            if (orderScheduleDto.getDealerId() != null && orderScheduleDto.getPeriods() == 1) {
                // 计算新增经销商订单排期应付款日期
                modifyDealerOrderSchedulePayableDate(orderScheduleDto.getOrderCode(), modifyDto.getPaySuccessTime(), modifyDto);
            }
            // 修改排期信息为已还款
            OrderScheduleRepaymentModifyDto repaymentModifyDto = new OrderScheduleRepaymentModifyDto();
            BeanUtils.copyProperties(modifyDto, repaymentModifyDto);
            repaymentModifyDto.setId(id);
            repaymentModifyDto.setPayWay(OrderPayWayEnum.OFFLINE);
            if (!orderScheduleService.modifyOrderScheduleRepayment(repaymentModifyDto)) {
                logger.error("[modifyOrderScheduleByOffline]修改排期信息异常:" + JSONObject.toJSONString(repaymentModifyDto));
                throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "排期信息修改失败");
            }

            result.put(id, Convert.toOrderScheduleOfflineBizDto(orderScheduleDto));
        }

        return result;
    }

    /**
     * 根据订单号和支付时间计算生成经销商订单排期应付款日期
     *
     * @param orderCode
     * @param paySuccessTime
     * @param modify
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean modifyDealerOrderSchedulePayableDate(Long orderCode, LocalDateTime paySuccessTime, OrderScheduleOfflineModifyDto modify)
            throws BizException {
        Boolean result = false;
		/*// 根据订单号查询经销商订单信息
		OrderDealerDetailBasicDto orderDealerDto = orderDealerService.getDetailBasic(orderCode);
		if (orderDealerDto == null) {
			logger.error("[modifyDealerOrderSchedulePayableDate]订单号：" + orderCode + "对应订单不存在");
			throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(), "订单信息不存在");
		}
		// 根据订单号查询排期信息
		List<OrderScheduleDto> orderScheduleDtoList = orderScheduleService.getOrderSchedule(orderCode);
		if (orderScheduleDtoList == null || orderScheduleDtoList.isEmpty()) {
			logger.error("[modifyDealerOrderSchedulePayableDate]订单号：" + orderCode + "对应排期不存在");
			throw new BizException(OrderExceptionCodeEnum.NOT_EXIST.getCode(), "订单排期信息不存在");
		}
		LocalDate time = paySuccessTime.toLocalDate();
		for (OrderScheduleDto orderScheduleDto : orderScheduleDtoList) {
			OrderSchedulePayableDateModifyDto modifyDto = new OrderSchedulePayableDateModifyDto();
			BeanUtils.copyProperties(orderScheduleDto, modifyDto);
			if (orderScheduleDto.getPeriods() == 1) {
				// 第一期，支付时间就是应付款日期
				modifyDto.setPayableDate(paySuccessTime.toLocalDate());
			} else {
				time = time.plus(orderDealerDto.getPaymentCycle(), ChronoUnit.MONTHS);
				// 其他期，根据订单信息计算
				modifyDto.setPayableDate(time);
			}

			if (!orderScheduleService.modifyDealerOrderSchedulePayableDate(modifyDto)) {
				logger.error("[modifyDealerOrderSchedulePayableDate]订单号：" + orderCode + "生成应付款日期失败");
				throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "生成应付款日期失败");
			}
		}*/
        //维护订单主状态
        Boolean orderStatus = orderDealerService.modifyOrderStatus(orderCode, OrderDealerStatusEnum.WAIT_DEPARTURE.getValue());
        if (!orderStatus) {
            logger.error("[modifyDealerOrderSchedulePayableDate]订单号：" + orderCode + "维护订单主状态失败");
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "维护订单主状态失败");
        }
        //状态流转记录
        OrderStatusFlowCreateDto orderStatusFlowCreateDto = new OrderStatusFlowCreateDto();
        orderStatusFlowCreateDto.setOrderCode(orderCode);
        orderStatusFlowCreateDto.setOrderStatus(OrderDealerStatusEnum.WAIT_DEPARTURE.getValue());
        orderStatusFlowCreateDto.setOrderModifiedType(OrderStatusFlowModifiedTypeEnum.B_USER.getValue());
        orderStatusFlowCreateDto.setOrderModifiedTime(LocalDateTime.now());
        if (null != modify.getOperateId() && null != modify.getOperateName()) {
            orderStatusFlowCreateDto.setOrderUserId(modify.getOperateId());
            orderStatusFlowCreateDto.setOrderUserName(modify.getOperateName());
        }
        Boolean orderStatusFlow = orderStatusFlowService.createOrderStatusFlow(orderStatusFlowCreateDto);
        if (!orderStatusFlow) {
            logger.error("[modifyDealerOrderSchedulePayableDate]订单号：" + orderCode + "插入订单状态流转记录失败");
            throw new BizException(OrderExceptionCodeEnum.ERROR.getCode(), "插入订单状态流转记录失败");
        }

        return result;
    }

    @Override
    public OrderDealerDetailBasicBizDto getOrderDealerDetailBasicBizDto(Long orderCode) throws Exception {
        OrderDealerDetailBasicBizDto orderDealerDetailBasicBizDto = null;

        OrderDealerDetailBasicDto orderDealerDetailBasicDto = orderDealerService.getDetailBasic(orderCode);
        if (null == orderDealerDetailBasicDto) {
            throw new Exception("非法入参");
        }
        orderDealerDetailBasicBizDto = new OrderDealerDetailBasicBizDto();
        BeanUtils.copyProperties(orderDealerDetailBasicDto, orderDealerDetailBasicBizDto);
        BigDecimal amountPaid = orderScheduleService.getAmountPaidByOrderCode(orderCode, OrderScheduleStatusEnum.ALREADY.getValue());
        if (null == amountPaid) {
            orderDealerDetailBasicBizDto.setAmountPaid(new BigDecimal("0"));
        } else {
            orderDealerDetailBasicBizDto.setAmountPaid(amountPaid);
        }

        List<OrderScheduleDto> orderScheduleDtoList = orderScheduleService.getOrderSchedule(orderCode);
        if (null == orderScheduleDtoList || orderScheduleDtoList.size() <= 0) {
            throw new Exception("非法入参");
        }
        Integer overduePeriods = 0;
        for (OrderScheduleDto orderScheduleDto : orderScheduleDtoList) {
            if (OrderScheduleStatusEnum.ALREADY == orderScheduleDto.getStatus()) {
                //第一期跳过
                if (1 != orderScheduleDto.getPeriods()) {
                    // 已还款
                    if (DateUtil.getDaysDiff(orderScheduleDto.getPayableDate(),
                            LocalDate.from(orderScheduleDto.getPaySuccessTime())) > 0) {
                        // 实际支付日期大于应支付日期
                        overduePeriods++;
                    }
                }
            } else {
                if (null != orderScheduleDto.getPayableDate()) {
                    // 未还款  (第一期跳过)
                    if (1 != orderScheduleDto.getPeriods() && DateUtil.getDaysDiff(orderScheduleDto.getPayableDate(), LocalDate.now()) > 0) {
                        // 当前日期大于应支付日期
                        overduePeriods++;
                    }
                }
            }
        }
        orderDealerDetailBasicBizDto.setPayable(orderScheduleDtoList.get(0).getPayable());
        orderDealerDetailBasicBizDto.setOverduePeriods(overduePeriods);
        orderDealerDetailBasicBizDto.setRentAmount(orderDealerDetailBasicDto.getRentAmount().add(orderDealerDetailBasicDto.getDepositAmount()));
        return orderDealerDetailBasicBizDto;
    }

    @Override
    public Map<LedgerRepaymentPeriodBizDto, String> getDealerRepaymentPeriod(List<LedgerRepaymentPeriodBizDto> params) throws Exception {
        Map<LedgerRepaymentPeriodBizDto, String> result = null;
        if (params == null || params.isEmpty()) {
            return result;
        }
        result = new HashMap<>();
        String cycleStr = null;
        for (LedgerRepaymentPeriodBizDto ledgerRepaymentPeriodBizDto : params) {
            List<OrderScheduleDto> orderScheduleDtoList = orderScheduleService.getOrderSchedule(ledgerRepaymentPeriodBizDto.getOrderCode());
            if (null == orderScheduleDtoList || orderScheduleDtoList.size() <= 0) {
                throw new Exception("订单号：" + ledgerRepaymentPeriodBizDto.getOrderCode() + "排期不存在");
            }
            for (OrderScheduleDto orderScheduleDto : orderScheduleDtoList) {
                if (ledgerRepaymentPeriodBizDto.getScheduleId().equals(orderScheduleDto.getId())) {
                    cycleStr = String.valueOf(orderScheduleDto.getPeriods()) + "/" + String.valueOf(orderScheduleDtoList.size());
                }
            }
            result.put(ledgerRepaymentPeriodBizDto, cycleStr);
        }

        return result;
    }

    /**
     * 审核驳回
     *
     * @param orderScheduleAuditModifyDto
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Boolean auditRejected(OrderScheduleAuditModifyDto orderScheduleAuditModifyDto) {

        for (Integer id : orderScheduleAuditModifyDto.getScheduleIds()) {
            orderScheduleService.modifyStatusByIdAndOrderCode(id, OrderScheduleStatusEnum.NO.getValue(), null);
            OrderScheduleDto orderScheduleDto = orderScheduleService.getOrderSchedule(id);
            // 如果是第一期则变更采购单主状态未已付首付款
            if (1 == orderScheduleDto.getPeriods()) {
                //主状态回滚
                orderDealerService.modifyOrderStatus(orderScheduleDto.getOrderCode(), OrderDealerStatusEnum.PREPAID_DOWN_PAYMENT.getValue());
                //状态记录回滚
                orderStatusFlowService.modifyDeleteDealerOrderStatusFlow(orderScheduleDto.getOrderCode(), OrderDealerStatusEnum.DOWN_PAYMENT_PAID.getValue());

            }
        }

        return true;
    }

    /**
     * 查询还款提醒消息
     *
     * @param payableDate 应还款日期
     * @param isAll       true:查询<payableDate，false：查询=payableDate
     * @param orderType   订单类型
     * @return
     */
    @Override
    public List<OrderScheduleReminderBizDto> getReminder(LocalDate payableDate, boolean isAll,
                                                         OrderTypeEnum orderType) {
        List<OrderScheduleReminderBizDto> result = null;
        // 判断订单类型
        if (OrderTypeEnum.EXCLUSIVEL.equals(orderType)) {
            // 专属订单（不包含长城汽车）
            List<OrderScheduleDto> orderScheduleDtos = orderScheduleService.getExclusivelUnpayPeriod(payableDate,
                    isAll);
            if (orderScheduleDtos == null || orderScheduleDtos.isEmpty()) {
                return result;
            }
            result = new ArrayList<>();
            for (OrderScheduleDto orderScheduleDto : orderScheduleDtos) {
                // 查询订单信息
                OrderExclusivelDto orderExclusivelDto = orderExclusivelService
                        .getOrderExclusivel(orderScheduleDto.getOrderCode());
                // 判断是否长城
                if (orderExclusivelDto == null
                        || OrderExclusivelTypeEnum.TYPE_TWO.equals(orderExclusivelDto.getType())) {
                    continue;
                }
                // 不是用车中订单，不提醒
                if (!OrderExclusivelStatusEnum.TRADE_USE.equals(orderExclusivelDto.getOrderStatus())) {
                    continue;
                }

                result.add(Convert.toOrderScheduleReminderBizDto(orderExclusivelDto, orderScheduleDto));
            }

        } else if (OrderTypeEnum.DEALER.equals(orderType)) {
            // 经销商订单
            List<OrderScheduleDto> orderScheduleDtos = orderScheduleService.getDealerUnpayPeriod(payableDate, isAll);
            if (orderScheduleDtos == null || orderScheduleDtos.isEmpty()) {
                return result;
            }
            result = new ArrayList<>();
            OrderScheduleReminderBizDto orderScheduleReminderBizDto = null;
            for (OrderScheduleDto orderScheduleDto : orderScheduleDtos) {
                OrderDealerDetailBasicDto orderDealerDetailBasicDto = orderDealerService.getDetailBasic(orderScheduleDto.getOrderCode());

                orderScheduleReminderBizDto = new OrderScheduleReminderBizDto();
                orderScheduleReminderBizDto.setDealerId(orderScheduleDto.getDealerId());
                orderScheduleReminderBizDto.setOrderCode(orderScheduleDto.getOrderCode());
                orderScheduleReminderBizDto.setPeriods(orderScheduleDto.getPeriods());
                orderScheduleReminderBizDto.setTotalPeriods(orderScheduleDto.getTotalPeriods());
                orderScheduleReminderBizDto.setDeposit(orderScheduleDto.getDeposit());
                orderScheduleReminderBizDto.setPayable(orderScheduleDto.getPayable());
                orderScheduleReminderBizDto.setCarCount(orderDealerDetailBasicDto.getRentNumbers());
                orderScheduleReminderBizDto.setStatus(orderScheduleDto.getStatus());
                orderScheduleReminderBizDto.setPayableDate(orderScheduleDto.getPayableDate());
                result.add(orderScheduleReminderBizDto);
            }

        }
        return result;
    }

    /**
     * 获取用户逾期续加入黑名单信息
     *
     * @param payableDate 应还款日期
     * @return
     */
    @Override
    public List<UserOverdueBlacklistBizDto> getUserOverdueBlacklist(LocalDate payableDate) {
        List<UserOverdueBlacklistBizDto> result = null;
        // 专属订单（不包含长城汽车）
        List<OrderScheduleDto> orderScheduleDtos = orderScheduleService.getExclusivelUnpayPeriod(payableDate, false);
        if (orderScheduleDtos == null || orderScheduleDtos.isEmpty()) {
            return result;
        }
        result = new ArrayList<>();
        List<Integer> userIds = new ArrayList<>();
        for (OrderScheduleDto orderScheduleDto1 : orderScheduleDtos) {
            if (userIds.contains(orderScheduleDto1.getUserId())) {
                continue;
            }
            userIds.add(orderScheduleDto1.getUserId());
            // 查询订单排期信息
            List<OrderScheduleDto> list = orderScheduleService.getOrderScheduleLtDate(orderScheduleDto1.getUserId(),
                    payableDate);
            int overdueContinueNoPay = 0, // 连续逾期未还次数
                    overdueSum = 0; // 累计逾期次数
            for (OrderScheduleDto orderScheduleDto2 : list) {
                if (OrderScheduleStatusEnum.NO.equals(orderScheduleDto2.getStatus())) {
                    overdueContinueNoPay += 1;
                    overdueSum += 1;
                } else if (OrderScheduleStatusEnum.ALREADY.equals(orderScheduleDto2.getStatus())) {
                    overdueContinueNoPay = overdueContinueNoPay >= 3 ? overdueContinueNoPay++ : 0;
                    if (DateUtil.getDaysDiff(orderScheduleDto2.getPayableDate(),
                            orderScheduleDto2.getPaySuccessTime()) > 0L) {
                        overdueSum += 1;
                    }
                } else {
                    overdueContinueNoPay = overdueContinueNoPay >= 3 ? overdueContinueNoPay++ : 0;
                }
            }
            if (overdueSum >= OrderConst.OVERDUE_ACCUMULATED) {
                // 大于累计上限，需加入黑名单
                result.add(new UserOverdueBlacklistBizDto(orderScheduleDto1.getUserId(),
                        "逾期累计超" + OrderConst.OVERDUE_ACCUMULATED + "次"));
            } else if (overdueContinueNoPay >= OrderConst.OVERDUE_CONTINUE) {
                // 大于连续未还上限，需加入黑名单
                result.add(new UserOverdueBlacklistBizDto(orderScheduleDto1.getUserId(),
                        "连续" + OrderConst.OVERDUE_CONTINUE + "次未还款"));
            }
        }

        return result;
    }

    /**
     * 计算逾期信息
     *
     * @param orderCode 订单号
     * @param date      计算日期
     * @return
     */
    @Override
    public OverdueBizDto getOverdue(Long orderCode, LocalDate date) {
        OverdueBizDto result = new OverdueBizDto(0, 0);
        // 根据订单号查询排期信息
        List<OrderScheduleDto> orderSchedules = orderScheduleService.getOrderSchedule(orderCode,
                OrderScheduleStatusEnum.NO);
        if (orderSchedules == null || orderSchedules.isEmpty()) {
            logger.info("[getOverdue]订单({})不存在未还排期信息", orderCode);
            return result;
        }
        // 遍历计算
        for (OrderScheduleDto orderSchedule : orderSchedules) {
            long daysDiff = DateUtil.getDaysDiff(orderSchedule.getPayableDate(), date);
            if (daysDiff <= 0) {
                break;
            }
            result.setOverdueNum(result.getOverdueNum() + 1);
            result.setOverdueDays(result.getOverdueDays() + (int) daysDiff);
        }

        return result;
    }
}
